#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
舆论监控Web面板

提供直观的Web界面进行舆论监控管理和数据展示。
"""

import asyncio
import json
import uuid
import sys
import os
from datetime import datetime, timedelta
from typing import Dict, List, Optional
import pandas as pd

# 添加项目根目录到 Python 路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from pywebio import start_server
import pywebio.input as pinput
import pywebio.output as poutput
from pywebio.session import run_async, run_js, set_env

from monitoring.monitor import SentimentMonitor, MonitorTarget, MonitorStatus
from monitoring.rules import MonitoringRules, MonitoringRule, RuleType, Severity
from monitoring.alerts import AlertManager, AlertChannel
from sentiment.analyzer import SentimentAnalyzer
from sentiment.keywords import KeywordManager

class SentimentDashboard:
    """舆论监控面板"""
    
    def __init__(self):
        # 初始化组件
        self.monitor = SentimentMonitor()
        self.rules = MonitoringRules()
        self.alert_manager = AlertManager()
        self.sentiment_analyzer = SentimentAnalyzer()
        self.keyword_manager = KeywordManager()
        
        # 当前页面状态
        self.current_page = "dashboard"
        
    async def main_interface(self):
        """主界面入口"""
        # 设置页面标题和样式
        set_env(title='舆论监控系统', output_animation=False)
        
        # 添加自定义CSS
        poutput.put_html("""
        <style>
        .metric-card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 10px;
            margin: 10px;
            text-align: center;
        }
        .alert-card {
            border-left: 4px solid #ff6b6b;
            padding: 15px;
            margin: 10px 0;
            background: #fff5f5;
        }
        .success-card {
            border-left: 4px solid #51cf66;
            padding: 15px;
            margin: 10px 0;
            background: #f0fff4;
        }
        .warning-card {
            border-left: 4px solid #ffd43b;
            padding: 15px;
            margin: 10px 0;
            background: #fffbe0;
        }
        .nav-button {
            margin: 5px;
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            background: #339af0;
            color: white;
        }
        .nav-button:hover {
            background: #1971c2;
        }
        .nav-button.active {
            background: #1864ab;
        }
        </style>
        """)
        
        # 主标题
        put_html('<h1>🎯 舆论监控系统</h1>')
        
        # 导航菜单
        await self.show_navigation()
        
        # 显示仪表板
        await self.show_dashboard()
        
        # 页面操作循环
        while True:
            # 等待用户操作
            await asyncio.sleep(1)
    
    async def show_navigation(self):
        """显示导航菜单"""
        put_html('<div id="navigation">')
        
        nav_buttons = [
            ("dashboard", "📊 仪表板"),
            ("targets", "🎯 监控目标"),
            ("rules", "📋 监控规则"),
            ("alerts", "🚨 告警管理"),
            ("analysis", "📈 数据分析"),
            ("settings", "⚙️ 系统设置")
        ]
        
        button_html = ""
        for page_id, label in nav_buttons:
            active_class = "active" if page_id == self.current_page else ""
            button_html += f'<button class="nav-button {active_class}" onclick="navigate_to(\'{page_id}\')">{label}</button>'
        
        put_html(button_html)
        put_html('</div>')
        
        # 注册JavaScript导航函数
        run_js("""
        function navigate_to(page) {
            pywebio.session.send_message('navigation', page);
        }
        """)
    
    async def show_dashboard(self):
        """显示主仪表板"""
        put_html('<div id="main-content">')
        
        # 系统状态概览
        await self.show_system_overview()
        
        # 实时监控状态
        await self.show_monitoring_status()
        
        # 最近告警
        await self.show_recent_alerts()
        
        # 趋势图表
        await self.show_trend_charts()
        
        put_html('</div>')
    
    async def show_system_overview(self):
        """显示系统概览"""
        put_html('<h2>📊 系统概览</h2>')
        
        # 获取统计数据
        monitor_status = self.monitor.get_monitor_status()
        alert_stats = self.alert_manager.get_statistics()
        rule_stats = self.rules.get_rule_statistics()
        
        # 创建指标卡片
        metrics = [
            {
                "title": "监控目标",
                "value": monitor_status["total_targets"],
                "subtitle": f"活跃: {monitor_status['active_targets']}"
            },
            {
                "title": "监控规则", 
                "value": rule_stats["total_rules"],
                "subtitle": f"启用: {rule_stats['enabled_rules']}"
            },
            {
                "title": "今日告警",
                "value": alert_stats["recent_24h"],
                "subtitle": f"成功率: {alert_stats['success_rate']:.1%}"
            },
            {
                "title": "系统状态",
                "value": monitor_status["status"].upper(),
                "subtitle": f"运行任务: {monitor_status['running_tasks']}"
            }
        ]
        
        # 显示指标卡片
        metric_cards = []
        for metric in metrics:
            card_html = f"""
            <div class="metric-card">
                <h3>{metric['value']}</h3>
                <p>{metric['title']}</p>
                <small>{metric['subtitle']}</small>
            </div>
            """
            metric_cards.append(put_html(card_html))
        
        put_row(metric_cards)
    
    async def show_monitoring_status(self):
        """显示监控状态"""
        put_html('<h2>🎯 监控状态</h2>')
        
        targets = self.monitor.get_targets()
        
        if not targets:
            put_warning("暂无监控目标，请添加监控目标开始监控。")
            put_button("添加监控目标", onclick=self.add_target_interface, color='primary')
            return
        
        # 监控目标表格
        table_data = []
        for target in targets:
            status_color = {
                'active': '🟢',
                'paused': '🟡', 
                'stopped': '🔴',
                'error': '❌'
            }.get(target['status'], '❓')
            
            last_check = target.get('last_check', '')
            if last_check:
                try:
                    last_check_dt = datetime.fromisoformat(last_check)
                    last_check_str = last_check_dt.strftime('%H:%M:%S')
                except:
                    last_check_str = last_check
            else:
                last_check_str = '从未'
            
            table_data.append([
                target['name'],
                target['target_type'],
                target['target_value'][:30] + '...' if len(target['target_value']) > 30 else target['target_value'],
                f"{status_color} {target['status']}",
                last_check_str,
                f"{target['monitor_frequency']}分钟",
                put_buttons([
                    {'label': '详情', 'value': f"detail_{target['id']}", 'color': 'info'},
                    {'label': '编辑', 'value': f"edit_{target['id']}", 'color': 'secondary'},
                    {'label': '删除', 'value': f"delete_{target['id']}", 'color': 'danger'}
                ], onclick=self.handle_target_action)
            ])
        
        put_table([
            ['名称', '类型', '目标值', '状态', '最后检查', '频率', '操作']
        ] + table_data)
        
        # 操作按钮
        put_row([
            put_button("添加目标", onclick=self.add_target_interface, color='primary'),
            put_button("启动监控", onclick=self.start_monitoring, color='success'),
            put_button("停止监控", onclick=self.stop_monitoring, color='warning'),
            put_button("刷新", onclick=self.refresh_dashboard, color='secondary')
        ])
    
    async def show_recent_alerts(self):
        """显示最近告警"""
        put_html('<h2>🚨 最近告警</h2>')
        
        alerts = self.alert_manager.get_alert_history(limit=10)
        
        if not alerts:
            put_info("暂无告警记录")
            return
        
        for alert in alerts:
            severity_class = {
                'critical': 'alert-card',
                'high': 'alert-card',
                'medium': 'warning-card',
                'low': 'success-card',
                'info': 'success-card'
            }.get(alert['severity'], 'success-card')
            
            severity_emoji = {
                'critical': '🚨',
                'high': '⚠️',
                'medium': '⚡',
                'low': 'ℹ️',
                'info': 'ℹ️'
            }.get(alert['severity'], 'ℹ️')
            
            timestamp = datetime.fromisoformat(alert['timestamp']).strftime('%m-%d %H:%M')
            
            alert_html = f"""
            <div class="{severity_class}">
                <strong>{severity_emoji} {alert['title']}</strong>
                <br><small>{timestamp} | {alert['type']} | 规则: {alert['rule_name']}</small>
                <p>{alert['content'][:200]}{'...' if len(alert['content']) > 200 else ''}</p>
            </div>
            """
            put_html(alert_html)
    
    async def show_trend_charts(self):
        """显示趋势图表"""
        put_html('<h2>📈 趋势分析</h2>')
        
        # 模拟数据（实际应该从数据库获取）
        put_html('<p>趋势图表功能开发中...</p>')
        
        # 这里可以集成图表库如ECharts或Chart.js
        # put_html("""
        # <div id="chart1" style="height: 300px;"></div>
        # <script>
        # // 图表代码
        # </script>
        # """)
    
    async def add_target_interface(self):
        """添加监控目标界面"""
        clear()
        put_html('<h2>➕ 添加监控目标</h2>')
        
        # 目标类型选择
        target_types = [
            ("keyword", "关键词监控"),
            ("video", "单视频监控"),
            ("user", "用户监控"),
            ("hashtag", "话题监控")
        ]
        
        # 输入表单
        form_data = input_group("监控目标配置", [
            input("name", label="目标名称", required=True, 
                 placeholder="输入监控目标的名称，如：品牌名称"),
            
            select("target_type", label="监控类型", options=target_types, required=True),
            
            textarea("target_value", label="监控内容", required=True,
                    placeholder="输入具体的监控内容：\\n- 关键词监控：输入关键词，如'美食'\\n- 单视频监控：输入视频URL\\n- 用户监控：输入用户ID或链接"),
            
            select("monitor_frequency", label="监控频率", 
                  options=[(30, "30分钟"), (60, "1小时"), (120, "2小时"), (360, "6小时"), (720, "12小时"), (1440, "24小时")],
                  value=60),
            
            slider("max_comments_per_video", label="每个视频最大评论数", 
                  min_value=10, max_value=200, value=50, step=10),
            
            checkbox("options", label="监控选项", 
                    options=[
                        ("include_replies", "包含评论回复"),
                        ("sentiment_analysis", "启用情感分析")
                    ],
                    value=["include_replies", "sentiment_analysis"])
        ])
        
        # 创建监控目标
        target = MonitorTarget(
            id=str(uuid.uuid4()),
            name=form_data["name"],
            target_type=form_data["target_type"],
            target_value=form_data["target_value"],
            monitor_frequency=form_data["monitor_frequency"],
            max_comments_per_video=form_data["max_comments_per_video"],
            include_replies="include_replies" in form_data["options"],
            sentiment_analysis="sentiment_analysis" in form_data["options"]
        )
        
        # 保存目标
        success = self.monitor.add_target(target)
        
        if success:
            put_success(f"监控目标 '{target.name}' 添加成功！")
            put_buttons([
                {'label': '返回仪表板', 'value': 'dashboard'},
                {'label': '继续添加', 'value': 'add_more'}
            ], onclick=self.handle_add_target_result)
        else:
            put_error("添加监控目标失败，请检查配置并重试。")
            put_button("重试", onclick=self.add_target_interface, color='primary')
    
    async def handle_add_target_result(self, choice):
        """处理添加目标结果"""
        if choice == 'dashboard':
            await self.show_dashboard()
        elif choice == 'add_more':
            await self.add_target_interface()
    
    async def handle_target_action(self, action):
        """处理目标操作"""
        action_type, target_id = action.split('_', 1)
        
        if action_type == 'detail':
            await self.show_target_detail(target_id)
        elif action_type == 'edit':
            await self.edit_target(target_id)
        elif action_type == 'delete':
            await self.delete_target(target_id)
    
    async def show_target_detail(self, target_id: str):
        """显示目标详情"""
        clear()
        put_html(f'<h2>🔍 监控目标详情</h2>')
        
        target = self.monitor.get_target(target_id)
        if not target:
            put_error("未找到指定的监控目标")
            return
        
        # 目标基本信息
        put_table([
            ['名称', target['name']],
            ['类型', target['target_type']],
            ['目标值', target['target_value']],
            ['状态', target['status']],
            ['监控频率', f"{target['monitor_frequency']}分钟"],
            ['最大评论数', target['max_comments_per_video']],
            ['包含回复', '是' if target['include_replies'] else '否'],
            ['情感分析', '是' if target['sentiment_analysis'] else '否'],
            ['创建时间', target['created_time']],
            ['最后检查', target.get('last_check', '从未')]
        ])
        
        # 最近的监控结果（模拟数据）
        put_html('<h3>📊 最近监控结果</h3>')
        put_info("监控结果历史功能开发中...")
        
        put_button("返回", onclick=lambda: asyncio.create_task(self.show_dashboard()))
    
    async def start_monitoring(self):
        """启动监控"""
        success = await self.monitor.start_monitoring()
        if success:
            put_success("监控已启动")
        else:
            put_error("监控启动失败")
        
        # 刷新界面
        await asyncio.sleep(1)
        await self.refresh_dashboard()
    
    async def stop_monitoring(self):
        """停止监控"""
        await self.monitor.stop_monitoring()
        put_warning("监控已停止")
        
        # 刷新界面
        await asyncio.sleep(1)
        await self.refresh_dashboard()
    
    async def refresh_dashboard(self):
        """刷新仪表板"""
        clear()
        await self.show_navigation()
        await self.show_dashboard()
    
    async def run_test_analysis(self):
        """运行测试分析"""
        clear()
        put_html('<h2>🧪 测试情感分析</h2>')
        
        # 测试文本输入
        test_data = input_group("测试情感分析", [
            textarea("test_text", label="测试文本", 
                    placeholder="输入要分析的文本，支持多行",
                    required=True),
            
            checkbox("analysis_options", label="分析选项",
                    options=[
                        ("show_details", "显示详细结果"),
                        ("show_keywords", "显示关键词匹配")
                    ],
                    value=["show_details"])
        ])
        
        # 执行分析
        put_html('<h3>🔬 分析结果</h3>')
        
        with put_loading():
            result = self.sentiment_analyzer.analyze_sentiment(test_data["test_text"])
        
        # 显示结果
        sentiment_color = {
            'positive': 'success',
            'negative': 'danger',
            'neutral': 'secondary'
        }.get(result['sentiment'], 'secondary')
        
        put_table([
            ['情感类别', put_tag(result['sentiment'], color=sentiment_color)],
            ['情感得分', f"{result['score']:.3f}"],
            ['置信度', f"{result['confidence']:.3f}"],
            ['威胁等级', f"{result['threat_level']}/5"],
            ['分析方法', result['method']]
        ])
        
        if "show_keywords" in test_data["analysis_options"] and result.get('keywords'):
            put_html('<h4>🏷️ 关键词匹配</h4>')
            keywords_html = ", ".join([f"<span style='background: #e9ecef; padding: 2px 6px; border-radius: 3px; margin: 2px;'>{kw}</span>" for kw in result['keywords']])
            put_html(keywords_html)
        
        if "show_details" in test_data["analysis_options"] and result.get('details'):
            put_html('<h4>📋 详细分析</h4>')
            put_code(json.dumps(result['details'], indent=2, ensure_ascii=False))
        
        put_button("返回仪表板", onclick=lambda: asyncio.create_task(self.show_dashboard()))
    
    def create_quick_actions(self):
        """创建快捷操作"""
        put_html('<h3>⚡ 快捷操作</h3>')
        
        quick_actions = [
            ("测试情感分析", self.run_test_analysis, 'info'),
            ("导出监控报告", self.export_report, 'secondary'),
            ("系统健康检查", self.system_health_check, 'warning'),
            ("清理历史数据", self.cleanup_data, 'danger')
        ]
        
        buttons = []
        for label, callback, color in quick_actions:
            buttons.append(put_button(label, onclick=callback, color=color))
        
        put_row(buttons)
    
    async def export_report(self):
        """导出监控报告"""
        put_info("报告导出功能开发中...")
    
    async def system_health_check(self):
        """系统健康检查"""
        put_info("系统健康检查功能开发中...")
    
    async def cleanup_data(self):
        """清理历史数据"""
        confirmed = await input("请输入'确认'以清理30天前的历史数据:", type=TEXT)
        
        if confirmed == '确认':
            # 执行清理
            self.alert_manager.cleanup_old_alerts(days=30)
            put_success("历史数据清理完成")
        else:
            put_warning("清理操作已取消")


def start_dashboard(port: int = 8082, debug: bool = False):
    """启动监控面板"""
    dashboard = SentimentDashboard()
    
    print(f"🎯 舆论监控系统启动中...")
    print(f"📱 Web面板地址: http://localhost:{port}")
    print(f"🔧 调试模式: {'开启' if debug else '关闭'}")
    
    start_server(
        dashboard.main_interface,
        port=port,
        debug=debug,
        auto_open_webbrowser=True
    )


if __name__ == "__main__":
    start_dashboard(port=8082, debug=True)